#ifndef __ERROR_H__
#define __ERROR_H__
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include "types.h"

#include <QtGui>
#include <QMainWindow>
#include <QImage>
#include <QLabel>
#include <qfiledialog.h>
#define DEBUG /* Debug mode on*/

namespace errlog {
	enum LogLevel {	maxverbose,
									verbose,
									warning,
									error,
									critical};

/* Logger */
class Logger {
	public:
	Logger();
	virtual void log(std::string file, int line, std::string s, std::string sFunc,LogLevel l) = 0;
	virtual ~Logger();
};
class PrintLogger : public Logger { //simple logger for printing
	public:
	PrintLogger();
	~PrintLogger();
	void log(std::string file, int line, std::string s, std::string sFunc, LogLevel l);
};
class DialogLogger : public Logger { //simple logger for dialogs
	public:
	DialogLogger();
	~DialogLogger();
	void log(std::string file, int line, std::string s, std::string sFunc, LogLevel l);
};
class FileLogger : public Logger{
private:
	std::ofstream	_fLog;
	bool			_bLog;
public:
	FileLogger(std::string s);
	~FileLogger();
	void log(std::string file, int line, std::string s, std::string sFunc, LogLevel l);
};


/* ErrorCtr*/
class ErrorCtr {
private:
	static ErrorCtr* _i;
	LogLevel _iLogLevel;
	typedef std::vector<Logger*> loggertype;
	loggertype _vLogger;
	ErrorCtr();
public:
	static std::string getLogLevelName(LogLevel l);
	~ErrorCtr();
	static ErrorCtr* getInstance();
	void setLogLevel(LogLevel l);
	LogLevel  getLogLevel() const;
	void addLogger(Logger*);
	void message(std::string file, int line,std::string s,std::string sFunc, LogLevel l);
};

}


#ifndef DEBUG
/* if not in debug mode drop verboses*/
#define MAXVERBOSE(s) ;
#define VERBOSE(s) ;
#else
/* use verboses*/
#define MAXVERBOSE(s) errlog::ErrorCtr::getInstance()->message(__FILE__,__LINE__,s,__PRETTY_FUNCTION__,errlog::maxverbose);
#define VERBOSE(s) errlog::ErrorCtr::getInstance()->message(__FILE__,__LINE__,s,__PRETTY_FUNCTION__,errlog::verbose);
#endif

#define WARNING(s) errlog::ErrorCtr::getInstance()->message(__FILE__,__LINE__,s,__PRETTY_FUNCTION__,errlog::warning);
#define ERROR(s) errlog::ErrorCtr::getInstance()->message(__FILE__,__LINE__,s,__PRETTY_FUNCTION__,errlog::error);
#define CRITICAL(s) errlog::ErrorCtr::getInstance()->message(__FILE__,__LINE__,s,__PRETTY_FUNCTION__,errlog::critical);
#endif
